home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
DJGPP
/
CBGRX103.ZIP
/
contrib
/
libgrx
/
src
/
drawtext.c
< prev
next >
Wrap
Text File
|
1993-12-06
|
10KB
|
353 lines
/**
** DRAWTEXT.C
**
** Copyright (C) 1992, Csaba Biegl
** 820 Stirrup Dr, Nashville, TN, 37221
** csaba@vuse.vanderbilt.edu
**
** This file is distributed under the terms listed in the document
** "copying.cb", available from the author at the address above.
** A copy of "copying.cb" should accompany this file; if not, a copy
** should be available from where this file was obtained. This file
** may not be distributed without a verbatim copy of "copying.cb".
** You should also have received a copy of the GNU General Public
** License along with this program (it is in the file "copying");
** if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
** Cambridge, MA 02139, USA.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**/
#include "grx.h"
#include "libgrx.h"
#include "grxfont.h"
#include "clipping.h"
#include "gmalloc.h"
#include "memfill.h"
#include "memcopy.h"
#include <string.h>
#define TXT_CLIP 1
#define TXT_NORMAL 0
#define TXT_ONEPIX 2
#define TXT_LARGE 4
#define BUILDMAT(m00,m01,m10,m11) \
{ mat00 = m00; mat01 = m01; mat10 = m10; mat11 = m11; }
#define MMULT_X(_x,_y) (mat00*(_x) + mat01*(_y))
#define MMULT_Y(_x,_y) (mat10*(_x) + mat11*(_y))
/*
#define UPDATE_X(x,y) x += MMULT_X(1,0),y += MMULT_Y(1,0)
#define UPDATE_Y(x,y) x += MMULT_X(0,1),y += MMULT_Y(0,1)
*/
#define UPDATE_X(x,y) x += mat00,y += mat10
#define UPDATE_Y(x,y) x += mat01,y += mat11
#define GETBITS() if((mask >>= 1) == 0) { bits = *bitmap++; mask = 0x80; }
void GrDrawString(char *text,int length,int x,int y,GrTextOption *opt)
{
GrFont *f = CHECK_FONT(opt->txo_font);
GrColorTableP fgcp,bgcp;
char far *bitmap,*tempp = NULL;
int type = opt->txo_chrtype;
int needs_clipping;
int mode,mode2,fixed;
int xchr,chr,attr;
int width,height;
int mat00,mat01;
int mat10,mat11;
int pixww,pixhh;
int pixdx,pixdy;
int chrww,chrhh;
int chrdx,chrdy;
int x1,x2,y1,y2;
int xdot,ydot;
int bits,mask;
int fgc,bgc;
int underline = 0;
int ww,hh;
MOUSE_FLAG;
if((f == NULL) ||
(_GrGetTextSize(text,length,&width,&height,opt) == FALSE) ||
(width == 0) ||
(height == 0))
return;
if((ww = width) < 0) { ww = (-ww); x += (ww - 1); }
if((hh = height) < 0) { hh = (-hh); y += (hh - 1); }
switch(opt->txo_xalign) {
case GR_ALIGN_RIGHT:
x -= (ww - 1);
break;
case GR_ALIGN_CENTER:
x -= (ww >> 1);
break;
}
switch(opt->txo_yalign) {
case GR_ALIGN_BASELINE:
if(opt->txo_direct == GR_TEXT_DEFAULT) y -= f->fnt_baseline;
break;
case GR_ALIGN_BOTTOM:
y -= (hh - 1);
break;
case GR_ALIGN_CENTER:
y -= (hh >> 1);
break;
}
x2 = (x1 = x) + width + ((width > 0) ? (-1) : 1);
y2 = (y1 = y) + height + ((height > 0) ? (-1) : 1);
needs_clipping = FALSE;
#undef WHEN_CLIPPED
#define WHEN_CLIPPED needs_clipping = TRUE
CLIPBOX(CURC,x1,y1,x2,y2);
MOUSE_BLOCK(CURC,x1,y1,x2,y2);
switch(type) {
case GR_ATTR_TEXT:
attr = (-1);
fgcp = opt->txo_fgcolor.p;
bgcp = opt->txo_bgcolor.p;
break;
case GR_WORD_TEXT:
default:
fgc = opt->txo_fgcolor.v;
bgc = opt->txo_bgcolor.v;
if(fgc & GR_UNDERLINE_TEXT) {
fgc &= ~GR_UNDERLINE_TEXT;
underline = f->fnt_undwidth;
}
if((fgc & (GrXOR | GrOR | GrAND)) == GrWRITE) {
_GrSetPixBlock(PIXEL_ADDR(x1,y1),bgc,x2-x1+1,y2-y1+1);
bgc = GrNOCOLOR;
}
}
switch(opt->txo_direct) {
case GR_TEXT_DOWN:
mode = TXT_ONEPIX;
pixww = opt->txo_ymag;
pixhh = opt->txo_xmag;
BUILDMAT(0,-pixww,pixhh,0);
break;
case GR_TEXT_LEFT:
mode = TXT_ONEPIX;
pixww = opt->txo_xmag;
pixhh = opt->txo_ymag;
BUILDMAT(-pixww,0,0,-pixhh);
break;
case GR_TEXT_UP:
mode = TXT_ONEPIX;
pixww = opt->txo_ymag;
pixhh = opt->txo_xmag;
BUILDMAT(0,pixww,-pixhh,0);
break;
default:
mode = TXT_NORMAL;
pixww = opt->txo_xmag;
pixhh = opt->txo_ymag;
BUILDMAT(pixww,0,0,pixhh);
break;
}
if((pixww > 1) || (pixhh > 1)) mode = TXT_LARGE;
if((pixdx = MMULT_X(1,1)) > 0) pixdx = 0; else pixdx++;
if((pixdy = MMULT_Y(1,1)) > 0) pixdy = 0; else pixdy++;
if((fixed = f->fnt_isfixed) != FALSE) {
width = f->fnt_width;
height = f->fnt_height;
chrdx = MMULT_X(width,0);
chrdy = MMULT_Y(width,0);
if((chrww = MMULT_X(width,height)) > 0) chrww--; else chrww++;
if((chrhh = MMULT_Y(width,height)) > 0) chrhh--; else chrhh++;
}
mode2 = mode;
while(--length >= 0) {
switch(type) {
case GR_WORD_TEXT:
chr = *((unsigned short *)text)++;
break;
case GR_ATTR_TEXT:
xchr = *((short *)text)++;
chr = xchr & 0xff;
if(attr != (xchr &= 0xff00)) {
fgc = (xchr >> 8) & 0x0f;
bgc = (xchr >> 12) & 0x07;
fgc = GR_CTABLE_COLOR(fgcp,fgc);
bgc = GR_CTABLE_COLOR(bgcp,bgc);
underline = (xchr & 0x8000) ? f->fnt_undwidth : 0;
attr = xchr;
}
break;
default:
chr = *((unsigned char *)text)++;
break;
}
if((chr > f->fnt_maxchar) || ((chr -= f->fnt_minchar) < 0)) {
if(fixed) {
x1 = x; x2 = x + chrww; x += chrdx;
y1 = y; y2 = y + chrhh; y += chrdy;
if(bgc == GrNOCOLOR) continue;
SORT2(x1,x2);
SORT2(y1,y2);
#undef WHEN_OUTSIDE
#undef WHEN_CLIPPED
#define WHEN_OUTSIDE continue
#define WHEN_CLIPPED
if(needs_clipping) CLIPSORTEDBOX(CURC,x1,y1,x2,y2);
_GrSetPixBlock(PIXEL_ADDR(x1,y1),bgc,x2-x1+1,y2-y1+1);
}
continue;
}
if(fixed)
bitmap = FFP(f)->ff_bits + (chr * FFP(f)->ff_chrsize);
else {
bitmap = PFP(f)->pf_bits[chr];
width = PFP(f)->pf_width[chr];
height = f->fnt_height;
chrdx = MMULT_X(width,0);
chrdy = MMULT_Y(width,0);
if((chrww = MMULT_X(width,height)) > 0) chrww--; else chrww++;
if((chrhh = MMULT_Y(width,height)) > 0) chrhh--; else chrhh++;
}
if(underline > 0) {
if(tempp == NULL)
tempp = _GrGetTempBuffer((fixed ? width : PFP(f)->pf_maxwidth) * height);
if(tempp != NULL) {
_ClrDir();
ww = (width + 7) >> 3;
hh = height - underline;
_SaveDS();
_RowCpyB(TXT,tempp,bitmap,(ww * hh));
_RestoreDS();
bitmap = &tempp[ww * hh];
_SaveDS();
_RowSetB(TXT,bitmap,0xff,(ww * underline));
_RestoreDS();
bitmap = tempp;
}
}
xdot = x; x += chrdx;
ydot = y; y += chrdy;
if(needs_clipping) {
x1 = xdot; x2 = xdot + chrww;
y1 = ydot; y2 = ydot + chrhh;
mode2 = mode;
#undef WHEN_CLIPPED
#define WHEN_CLIPPED mode2 |= TXT_CLIP
CLIPBOX(CURC,x1,y1,x2,y2);
}
xdot += pixdx;
ydot += pixdy;
switch(mode2) {
case TXT_NORMAL:
_GrDrawChar(PIXEL_ADDR(xdot,ydot),width,height,bitmap,fgc,bgc);
break;
case TXT_ONEPIX:
for(hh = height; --hh >= 0; UPDATE_Y(xdot,ydot)) {
x1 = xdot; y1 = ydot;
for(mask = 0,ww = width; --ww >= 0; UPDATE_X(x1,y1)) {
GETBITS();
if(bits & mask) {
_GrSetPixel(PIXEL_ADDR(x1,y1),fgc);
}
else if(bgc != GrNOCOLOR) {
_GrSetPixel(PIXEL_ADDR(x1,y1),bgc);
}
}
}
break;
case (TXT_NORMAL | TXT_CLIP):
case (TXT_ONEPIX | TXT_CLIP):
for(hh = height; --hh >= 0; UPDATE_Y(xdot,ydot)) {
x1 = xdot; y1 = ydot;
for(mask = 0,ww = width; --ww >= 0; UPDATE_X(x1,y1)) {
GETBITS();
#undef WHEN_CLIPPED
#define WHEN_CLIPPED
CLIPDOT(CURC,x1,y1);
if(bits & mask) {
_GrSetPixel(PIXEL_ADDR(x1,y1),fgc);
}
else if(bgc != GrNOCOLOR) {
_GrSetPixel(PIXEL_ADDR(x1,y1),bgc);
}
}
}
break;
case TXT_LARGE:
for(hh = height; --hh >= 0; UPDATE_Y(xdot,ydot)) {
x1 = xdot; y1 = ydot;
for(mask = 0,ww = width; --ww >= 0; UPDATE_X(x1,y1)) {
GETBITS();
if(bits & mask) {
_GrSetPixBlock(PIXEL_ADDR(x1,y1),fgc,pixww,pixhh);
}
else if(bgc != GrNOCOLOR) {
_GrSetPixBlock(PIXEL_ADDR(x1,y1),bgc,pixww,pixhh);
}
}
}
break;
case (TXT_LARGE | TXT_CLIP):
for(hh = height; --hh >= 0; UPDATE_Y(xdot,ydot)) {
int x0 = xdot, y0 = ydot;
for(mask = 0,ww = width; --ww >= 0; UPDATE_X(x0,y0)) {
GETBITS();
x2 = (x1 = x0) + pixww - 1;
y2 = (y1 = y0) + pixhh - 1;
CLIPSORTEDBOX(CURC,x1,y1,x2,y2);
if(bits & mask) {
_GrSetPixBlock(PIXEL_ADDR(x1,y1),
fgc,
(x2 - x1 + 1),
(y2 - y1 + 1)
);
}
else if(bgc != GrNOCOLOR) {
_GrSetPixBlock(PIXEL_ADDR(x1,y1),
bgc,
(x2 - x1 + 1),
(y2 - y1 + 1)
);
}
}
}
break;
}
}
MOUSE_UNBLOCK();
}
void GrDrawChar(int chr,int x,int y,GrTextOption *opt)
{
char cbuff[2];
short sbuff[2];
switch(opt->txo_chrtype) {
case GR_WORD_TEXT:
case GR_ATTR_TEXT:
sbuff[0] = chr;
GrDrawString((char *)sbuff,1,x,y,opt);
break;
default:
cbuff[0] = chr;
GrDrawString(cbuff,1,x,y,opt);
break;
}
}
void GrTextXY(int x,int y,char *text,int fg,int bg)
{
static GrTextOption opt = { NULL, 1, 1, 0 };
if(opt.txo_font == NULL) opt.txo_font = CHECK_FONT(NULL);
opt.txo_fgcolor.v = fg;
opt.txo_bgcolor.v = bg;
GrDrawString(text,strlen(text),x,y,&opt);
}